﻿using Newtonsoft.Json;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using Test;
using Test.control;

public class TestClient
{
    public string appid;
    public string pwd;

    public int _state = 0;
    public string info;

    private List<ServerItem> serverList;
    private int serverIndex = 0;
    private int netErrorCount = 0;

    private WebSocket net;
    private List<byte[]> recv = new List<byte[]>();
    private string tttoken;
    private float heartTime = 0;

    private bool hasRun = false;
    private bool hasSendRoom = false;
    
    private ClientItemUI ui;

    public int state
    {
        set
        {
            _state = value;
            ui.BeginInvoke((Action)(() =>
            {
                ui.SetState(_state);
            }));
        }
        get
        {
            return _state;
        }
    }

    private int _recvCount;

    public int recvCount
    {
        set
        {
            _recvCount = value;
            ui.BeginInvoke((Action)(() =>
            {
                ui.SetRecvCount(_recvCount);
            }));
        }
        get
        {
            return _recvCount;
        }
    }

    public Form1 form;
    private float heartRecvTime;

    public TestClient(Form1 form, string appid,string token,int index, ClientItemUI ui)
    {
        this.form = form;
        this.appid = appid;
        this.tttoken = token;
        this.ui = ui;
        this.ui.SetIndex(index);
    }

    public async Task getServerList()
    {
        try
        {
            using (HttpClient client = new HttpClient())
            {
                var responseString = await client.GetStringAsync(string.Format("http://{0}:{1}/games?appid=test", Form1.ip, Form1.gatePort));
                Console.WriteLine(responseString);
                this.serverList = JsonConvert.DeserializeObject<List<ServerItem>>(responseString);
            }
            this.netErrorCount = 0;
            this.state = 1;
            _ = this.initNetWork();
        }
        catch (Exception e)
        {
            state = -1;
            debug(e.ToString());
            await Task.Delay(3000);
            _ = getServerList();
        }
    }

    private async Task initNetWork()
    {
        if (this.serverList == null || this.serverList.Count <= 0)
        {
            debug("[网络]getServerList,返回数据为空");
            await Task.Delay(3000);
            _ = this.getServerList();
        }
        else
        {
            this.net = new WebSocket();
            //this.net.debug = this.debug;
            this.net.ConnError = this.connectClose;
            this.net.ConnOk = this.connOk;
            this.ConnAction();
        }
    }
    private void ConnAction()
    {
        recvCount = 0;
        if (this.serverIndex >= this.serverList.Count)
        {
            this.serverIndex = 0;
        }
        var obj = this.serverList[this.serverIndex];
        //this.pwd = obj.pwd;
        string url = string.Format("ws://{0}:{1}/ws", obj.ip, obj.port);
        debug("[网络]连接:" + url);
        _ = net.Connect(url);
    }

    private void connOk()
    {
        debug("[网络]connectOk");
        this.state = 2;
        var obj = new LoginObj();
        obj.type = "login";
        obj.pwd = "";
        obj.check = 0;
        obj.mac = "1.0.1";
        obj.token = this.tttoken;
        var str = JsonConvert.SerializeObject(obj);
        this.Send(str);
    }

    private void connectClose()
    {
        debug("[网络]connectClose:" + this.netErrorCount + ":" + this.serverIndex);
        state = -1;
        debug("[网络]异常");
        this.net.clear();
        _ = this.ReConn();
    }

    public async Task ReConn()
    {
        await Task.Delay(3000);
        this.netErrorCount++;
        if (this.netErrorCount >= 3)
        {
            this.serverIndex++;
            this.netErrorCount = 0;
            if (this.serverIndex >= this.serverList.Count)
            {
                _ = this.getServerList();
            }
        }
        this.ConnAction();
    }

    public void Send(string str)
    {
        byte[] data = System.Text.Encoding.UTF8.GetBytes(str);
        this.net.Send(data);
    }

    public void Update()
    {
        if (net != null && !net.isOver)
        {
            recv.Clear();
            net.Recv(recv);
            if (recv.Count > 0)
            {
                for (int i = 0; i < recv.Count; i++)
                {
                    var sdkStr = System.Text.Encoding.UTF8.GetString(recv[i]); // Convent<Protocol.pkgSDKData>(recv[i]);
                    var sdkData = JsonConvert.DeserializeObject<sdkData>(sdkStr);
                    if (sdkData.token != this.tttoken)
                    {
                       Console.WriteLine("收到其他房间的消息:" + sdkData.token);
                    }
                    else
                    {
                        switch (sdkData.type)
                        {
                            case "loginOk"://登录成功
                                net.loginOk = true;
                                this.heartTime = Time.time;
                               Console.WriteLine("[网络]登录ok");

                                hasSendRoom = true;
                                var upRoomData = new UpRoomInfo();
                                upRoomData.appid = appid;
                                upRoomData.token = this.tttoken;
                                upRoomData.type = "tt_room";
                                var upstr = JsonConvert.SerializeObject(upRoomData);
                                this.Send(upstr);
                               Console.WriteLine("[网络]上传房间信息");
                                break;
                            case "loginError"://登录失败
                                Console.WriteLine("[网络]登录失败");
                                connectClose();
                                break;
                            case "room_state"://房间状态
                               Console.WriteLine("房间状态:" + sdkData.data);
                                switch (sdkData.data)
                                {
                                    case "-1"://房间不存在
                                        debug("房间号错误");
                                        if (hasSendRoom)
                                        {
                                            hasRun = false;
                                        }
                                        connectClose();
                                        break;
                                    case "1"://开始任务
                                        debug("开始");
                                        this.state = 4;
                                        break;
                                }
                                break;
                            case "tt_heart":
                                
                                heartRecvTime = Time.time;
                                break;
                            case "live_comment"://直播间评论
                                heartRecvTime = Time.time;
                                this.recvCount++;
                               Console.WriteLine("收到聊天消息:" + sdkData.roomid + ":" + sdkData.data);

                                break;
                            case "live_gift"://直播间送礼
                                heartRecvTime = Time.time;
                                this.recvCount++;
                                Console.WriteLine("收到礼物消息:" + sdkData.roomid + ":" + sdkData.data);
                                break;
                            case "live_like"://点赞
                                heartRecvTime = Time.time;
                                this.recvCount++;
                                //Debug.Log("收到点赞消息:" + sdkData.Roomid + ":" + sdkData.Data);
                                //info.Add("[点赞]" + sdkData.Data);
                                break;
                            case "gz"://关注
                                heartRecvTime = Time.time;
                                this.recvCount++;
                                Console.WriteLine("收到关注消息:" + sdkData.roomid + ":" + sdkData.data);
                                break;
                        }
                    }
                }
            }
            if (net.loginOk)
            {
                if (Time.time - this.heartTime >= 3)
                {//发送心跳包
                    if (!string.IsNullOrEmpty(this.tttoken))
                    {
                        this.heartTime = Time.time;

                        var heartObj = new Heart();
                        heartObj.type = "tt_heart";
                        heartObj.token = this.tttoken;
                        var str = JsonConvert.SerializeObject(heartObj);
                        var heartBytes = System.Text.Encoding.UTF8.GetBytes(str);

                        this.net.Send(heartBytes);
                    }
                }
            }
        }
    }


    public void debug(string str)
    {
        ui.BeginInvoke((Action)(() =>
        {
            ui.SetInfo(str);
        }));
    }
}

//===========
//=================
//登录
public struct LoginObj
{
    public string type;
    /// <summary>
    /// 是否需要验证
    /// </summary>
    public int check;
    /// <summary>
    /// 密码
    /// </summary>
    public string pwd;
    /// <summary>
    /// mac地址
    /// </summary>
    public string mac;
    /// <summary>
    /// token
    /// </summary>
    public string token;
    /// <summary>
    /// 版本号
    /// </summary>
    public string version;
}
//心跳
public struct Heart
{
    public string type;
    public string token;
}
//心跳
public struct UpRoomInfo
{
    public string type;
    public string token;
    public string appid;
}

[System.Serializable]
public struct sdkData
{
    public string type;
    public string token;
    public string roomid;
    public string data;
}
